package com.harmontronics.hanma.paas.paas.domain.iam.service;

import cn.hutool.core.convert.Convert;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.harmontronics.hanma.paas.paas.consts.NumberEnum;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.GroupManage;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.GroupManageUser;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.valueobject.Constants;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.valueobject.HmUserGroupManageFields;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.valueobject.I18nKeyEnum;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.persistence.HmUserGroupManageRepository;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.HmUserGroupManage;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.persistence.HmUserGroupRepository;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.po.HmUserGroupMemberPO;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.po.HmUserGroupPO;
import com.harmontronics.hanma.paas.paas.exception.ErrorKeyException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.harmontronics.hanma.paas.paas.common.PageBase;

import com.harmontronics.hanma.paas.paas.domain.iam.repository.mapper.HmUserGroupManageMapper;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.po.HmUserGroupManagePO;
import java.util.List;

@Service("hmUserGroupManageService")
@DS("#header.App-Unique")
public class HmUserGroupManageService{

    @Autowired
    private HmUserGroupManageRepository hmUserGroupManageRepository;

    @Autowired
    private HmUserGroupManageMapper hmUserGroupManageMapper;

    @Autowired
    private HmUserGroupRepository hmUserGroupRepository;

    @Autowired
    private HmUserGroupService hmUserGroupService;

    @Autowired
    private HmUserGroupMemberService hmUserGroupMemberService;


    public void removeManagerById(Long id) {
        hmUserGroupManageRepository.removeById(id);
    }

    public List<HmUserGroupManage> getList(){
        List<HmUserGroupManagePO> pos =  hmUserGroupManageRepository.list();
        return Convert.toList(HmUserGroupManage.class,pos) ;
    }

    public PageBase<HmUserGroupManage> getList(int pageNo,int pageSize){
        Page<HmUserGroupManagePO> page = new Page<>(pageNo, pageSize);
        IPage<HmUserGroupManagePO> resultPage =
                    hmUserGroupManageRepository.selectPage(Wrappers.emptyWrapper(),page);
        return PageBase.from(resultPage,HmUserGroupManage.class);
    }

    /**
     * 获取相应的用户组ID（管理员及成员）
     */
    public List<Long> selectGroupIdsWithOrgIdAndUserId(List<Long> orgIds, Long userId) {
        return hmUserGroupManageMapper.selectGroupIdsWithOrgIdAndUserId(orgIds, userId);
    }

    /**
     * 根据用户id查询所有的 用户组-管理员
     */
    public List<HmUserGroupManagePO> selectGroupManageWithUserId(Long userId) {
        return hmUserGroupManageMapper.selectList(
                new QueryWrapper<HmUserGroupManagePO>().eq(HmUserGroupManageFields.USER_ID, userId));
    }

    public List<GroupManageUser> selectGroupManageUserWithId(Long groupId) {
        List<GroupManageUser> groupManageUserList = new ArrayList<>();
        // 查询当前角色 管理员列表
        groupManageUserList.addAll(hmUserGroupManageMapper.selectGroupManageUserWithGroupId(groupId));
        return groupManageUserList;
    }

    public void create(List<GroupManage> groupManageCreateList) {
        if (CollectionUtils.isNotEmpty(groupManageCreateList)) {
            List<ErrorKeyException> exceptionList = new ArrayList<>();
            for (GroupManage groupManageCreate : groupManageCreateList) {
                try {
                    insertSingleManager(groupManageCreate);
                } catch (ErrorKeyException exception) {
                    exceptionList.add(exception);
                }
            }
            if (CollectionUtils.isNotEmpty(exceptionList)) {
                throw exceptionList.get(0);
            }
        }
    }

    private void insertSingleManager(GroupManage groupManageCreate)
            throws ErrorKeyException {

        //判断用户是否已经是该组的管理员
        QueryWrapper<HmUserGroupManagePO> queryWrapper = new QueryWrapper<>();
        queryWrapper.
                eq(HmUserGroupManageFields.USER_GROUP_ID,groupManageCreate.getGroupId()).
                eq(HmUserGroupManageFields.USER_ID,groupManageCreate.getUserId()).
                eq(HmUserGroupManageFields.DELETED,NumberEnum.ZERO.getNum());
        HmUserGroupManagePO po = hmUserGroupManageMapper.selectOne(queryWrapper);
        if(Optional.ofNullable(po).isPresent()){
            return;
        }
        /**
         * 如果一个用户是父用户组的管理员，则无法再添加为子用户组的管理员或成员，添加是给出提示"该用户已经拥有该用户组的管理权限"
         * 如果一个用户是子用户组的管理员或成员，则无法再添加为父用户的管理员，添加是给出提示"该用户已经是该子用户组的管理员或成员"
         */
        checkUser(groupManageCreate.getUserId(), groupManageCreate.getGroupId());

        // 判断当前用户是否是组员，如果是，则给提示
        checkUserInGroupMember(
                groupManageCreate.getUserId(),
                groupManageCreate.getGroupId(),
                groupManageCreate.getIsInsert());

        HmUserGroupManagePO userGroupManage =
                new HmUserGroupManagePO()
                        .setUserGroupId(groupManageCreate.getGroupId())
                        .setUserId(groupManageCreate.getUserId());
        hmUserGroupManageMapper.insert(userGroupManage);
    }

    public void checkUser( Long userId, Long groupId) {

        // 如果一个用户是父用户的管理员，则无法再添加为子用户组的管理员或成员，添加是给出提示"该用户已经拥有该用户组的管理权限"
        checkUserIsParentAdmin(userId, groupId);

        // 如果一个用户是子用户组的管理员或成员，则无法再添加为父用户的管理员，添加是给出提示"该用户已经是该子用户组的管理员或成员"
        checkUserIsInChildGroup(userId, groupId);
    }

    /**
     * 如果一个用户是父用户的管理员 则无法再添加为子用户组的管理员或成员 添加时给出提示"该用户已经拥有该用户组的管理权限"
     */
    private void checkUserIsParentAdmin(Long userId, Long groupId) {
        // 查看父节点管理员中是否含有当前用户
        List<HmUserGroupManagePO> groupMembers = getParentUserGroupWithUserIdAndGroupId(userId,
                groupId);
        if (CollectionUtils.isNotEmpty(groupMembers)) {
            throw new ErrorKeyException(I18nKeyEnum.CURRENT_USER_IS_MANAGE);
        }
    }

    private List<HmUserGroupManagePO> getParentUserGroupWithUserIdAndGroupId(Long userId,
            Long groupId) {
        // 查询出当前用户组所在的节点
        HmUserGroupPO groupManage = hmUserGroupRepository.getById(groupId);
        List<HmUserGroupManagePO> groupManageList = new ArrayList<>();
        if (groupManage != null) {
            String parentIds = groupManage.getParentIds();
            if (StringUtils.isNotEmpty(parentIds)){
                List<Long> userGroupIdList =
                        Arrays.stream(
                                parentIds
                                        .substring(
                                                NumberEnum.ONE.getNum(),
                                                parentIds.length() - NumberEnum.ONE.getNum())
                                        .split(Constants.PARENTID))
                                .mapToLong(Long::parseLong)
                                .boxed()
                                .collect(Collectors.toList());

                if (CollectionUtils.isNotEmpty(userGroupIdList)) {
                    groupManageList = hmUserGroupManageMapper.selectParentUserGroupWithUserIdAndGroupId(
                            userId, userGroupIdList);
                }
            }


        }
        return groupManageList;
    }

    /**
     * 如果一个用户是子用户组的管理员或成员，则无法再添加为父用户的管理员，添加是给出提示"该用户已经是该子用户组的管理员"
     */
    private void checkUserIsInChildGroup(Long userId, Long groupId) {
        // 查看子节点管理员中是否含有当前用户
        List<HmUserGroupManagePO> groupMembers = getChildUserGroupWithUserIdAndGroupId(userId,
                groupId);
        if (CollectionUtils.isNotEmpty(groupMembers)) {
            throw new ErrorKeyException(I18nKeyEnum.CURRENT_USER_IS_MANAGE);
        }
    }

    /**
     * 查看子节点管理员中是否含有当前用户
     */
    private List<HmUserGroupManagePO> getChildUserGroupWithUserIdAndGroupId(Long userId,
            Long groupId) {
        // 查询子用户组
        List<Long> childUserGroup = hmUserGroupService.selectChildIdWithParentId(groupId);
        List<HmUserGroupManagePO> groupManageList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(childUserGroup)) {
            if (CollectionUtils.isNotEmpty(childUserGroup)) {
                groupManageList = hmUserGroupManageMapper.selectParentUserGroupWithUserIdAndGroupId(
                        userId, childUserGroup);
            }
        }
        return groupManageList;
    }

    /**
     * 判断当前用户是否是组员，如果是，则给提示
     */
    private void checkUserInGroupMember(Long userId, Long groupId, Integer isInsert) {
        if (!isInsert.equals(NumberEnum.ONE.getNum())) {
            List<HmUserGroupMemberPO> memberList =
                    hmUserGroupMemberService.selectGroupMemberWithUserId(userId, groupId);
            if (CollectionUtils.isNotEmpty(memberList)) {
                // 和前端约定好的code，更改需要确认
                throw new ErrorKeyException(I18nKeyEnum.CURRENT_USER_IS_MANAGE);
            }
        } else {
            // 删除用户组成员中的数据
            hmUserGroupMemberService.delete(userId, groupId, NumberEnum.ZERO.getNum());
        }
    }

    /**
     * 根据用户id和用户组id查询当前是否在管理员中
     */
    public List<HmUserGroupManagePO> selectGroupManageUserWithUserIdAndGroupId(
            Long userId, Long userGroupId) {
        return hmUserGroupManageMapper.selectList(
                new QueryWrapper<HmUserGroupManagePO>()
                        .eq(HmUserGroupManageFields.USER_ID, userId)
                        .eq(HmUserGroupManageFields.USER_GROUP_ID, userGroupId));
    }

}